package com.ecomm.util.struts;

import org.apache.struts.action.RequestProcessor;
import org.apache.struts.tiles.TilesRequestProcessor;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.config.ModuleConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.struts.DelegatingActionUtils;
import org.springframework.beans.BeansException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: Gavin
 * Date: 2007-3-1
 * Time: 21:27:10
 * To change this template use File | Settings | File Templates.
 */
public class DelegatingRequestProcessor extends RequestProcessor {
    private WebApplicationContext webApplicationContext;


        public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
            super.init(actionServlet, moduleConfig);
            if (actionServlet != null) {
                this.webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
            }
        }

        /**
         * Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
         * falling back to the root WebApplicationContext. This context is supposed
         * to contain the Struts Action beans to delegate to.
         * @param actionServlet the associated ActionServlet
         * @param moduleConfig the associated ModuleConfig
         * @return the WebApplicationContext
         * @throws IllegalStateException if no WebApplicationContext could be found
         * @see org.springframework.web.struts.DelegatingActionUtils#findRequiredWebApplicationContext
         * @see org.springframework.web.struts.ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
         */
        protected WebApplicationContext initWebApplicationContext(
                ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {

            return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
        }

        /**
         * Return the WebApplicationContext that this processor delegates to.
         */
        protected final WebApplicationContext getWebApplicationContext() {
            return webApplicationContext;
        }


        /**
         * Override the base class method to return the delegate action.
         * @see #getDelegateAction
         */
        protected Action processActionCreate(
                HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
                throws IOException {

            Action action = getDelegateAction(mapping);
            if (action != null) {
                return action;
            }
            return super.processActionCreate(request, response, mapping);
        }

        /**
         * Return the delegate Action for the given mapping.
         * <p>The default implementation determines a bean name from the
         * given ActionMapping and looks up the corresponding bean in the
         * WebApplicationContext.
         * @param mapping the Struts ActionMapping
         * @return the delegate Action, or <code>null</code> if none found
         * @throws org.springframework.beans.BeansException if thrown by WebApplicationContext methods
         * @see #determineActionBeanName
         */
        protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
            String beanName = determineActionBeanName(mapping);
            if (!getWebApplicationContext().containsBean(beanName)) {
                return null;
            }
            return (Action) getWebApplicationContext().getBean(beanName, Action.class);
        }

        /**
         * Determine the name of the Action bean, to be looked up in
         * the WebApplicationContext.
         * <p>The default implementation takes the mapping path and
         * prepends the module prefix, if any.
         * @param mapping the Struts ActionMapping
         * @return the name of the Action bean
         * @see DelegatingActionUtils#determineActionBeanName
         * @see org.apache.struts.action.ActionMapping#getPath
         * @see org.apache.struts.config.ModuleConfig#getPrefix
         */
        protected String determineActionBeanName(ActionMapping mapping) {
            return DelegatingActionUtils.determineActionBeanName(mapping);
        }

}
